/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: Huang xiaoji
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **     Uncompress the program files.
 **    
 ****************************************************************/
package com.hp.snap.gr.action.impl;

import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.model.jaxb.ActionType;
import com.hp.snap.gr.model.jaxb.GeneralActionType;
import com.hp.snap.gr.utils.GRMConfigManager;
import com.hp.snap.gr.utils.SSHTools;
import com.hp.snap.gr.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Map;

/**
 * 
 * Uncompress the program files. Get a ProgramFiles.zip file from the configured path, copy to temp folder of current
 * deployment site host , and then uncompress the zip file.
 * 
 * The action have a parameter need to be configured: SourcePath:
 * SourcePath: The source folder of program file zip.
 * 
 * <P>
 * Version: 3.3 <br>
 * Author: Huang xiaoji Date: Apr 10, 2015
 * 
 * </P>
 * 
 **/
public class DecompressProgramFilesActionHandler extends AbstractActionHandler {
    private static final Logger logger = LoggerFactory.getLogger(DecompressProgramFilesActionHandler.class);
    private SSHTools ssh = new SSHTools(null, null);

    @Override
    public void execute(ActionType action, Map<String, Object> actionPlanInputs, Map<String, Object> actionPlanOutputs) throws ActionException {
        if (action instanceof GeneralActionType) {
            GeneralActionType actionType = (GeneralActionType) action;

            String sourceRoot = actionType.getParameter().get(0).getVal();
            if (logger.isDebugEnabled()) {
                logger.debug("The decompressed source root is {}", sourceRoot);
            }
            File source = new File(sourceRoot, "ProgramFiles.zip");
            if (!source.exists()) {
                throw new ActionException("The decompressed source file is not exists.");
            }

            Map<String, Map<String, Object>> hosts = Utils.getAllHostsInSite(GRMConfigManager.getSiteName());
            for (Map.Entry<String, Map<String, Object>> entry : hosts.entrySet()) {
                if (logger.isTraceEnabled()) {
                    logger.trace("processing host {} {}", entry.getKey(), entry.getValue());
                }
                String hostIP = (String) entry.getValue().get("HOST_IP");
                String[] files = (String[]) entry.getValue().get("FILES");

                if (hostIP != null && files != null && files.length > 0) {
                    //copy to destination
                    String fn = copy(source, hostIP);
                    for (String file : files) {
                        decompress("/tmp/" + fn, hostIP, file.substring(1));
                    }
                    //remove destination
                    clean(fn, hostIP);
                }
            }
        }
    }

    private void clean(String source, String hostIP) throws ActionException {
        try {
            ssh.cmd(hostIP, "rm -f /tmp/" + source);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ActionException(e);
        }
    }

    private void decompress(String source, String hostIP, String file) throws ActionException {
        try {
            String rs = ssh.cmd(hostIP, "unzip -d / -o " + source + " " + file + "/*");
            if (ssh.getExitStatusOfCommandResult(rs) != 0) {
                logger.debug("there are no {} installed in {}", file, hostIP);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ActionException(e);
        }
    }

    private String copy(File source, String hostIP) throws ActionException {
        String fName = "F" + System.currentTimeMillis() + ".zip";

        try {
            ssh.copyFromLocal(source.getAbsolutePath(), hostIP, "/tmp/" + fName);
            return fName;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ActionException(e);
        }
    }
}
